package com.ai.aicodemather.core;

import com.ai.aicodemather.ai.AiCodeGeneratorService;
import com.ai.aicodemather.ai.model.HtmlCodeResult;
import com.ai.aicodemather.ai.model.MultiFileCodeResult;
import com.ai.aicodemather.core.parser.CodeParseExecutor;
import com.ai.aicodemather.core.saver.CodeFileSaverExecutor;
import com.ai.aicodemather.exception.BusinessException;
import com.ai.aicodemather.exception.ErrorCode;
import com.ai.aicodemather.model.enums.CodeGenTypeEnum;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;

import java.io.File;

/**
 * 自定义门面模式，组合ai代码生成和代码文件保存
 */
@Component
@Slf4j
public class AiCodeGeneratorFacade {

    @Resource
    private AiCodeGeneratorService aiCodeGeneratorService;


    /**
     * 生成代码文件
     *
     * @param userMessage
     * @param codeGenTypeEnum
     * @return
     */
    public File generateAndSaveCode(String userMessage, CodeGenTypeEnum codeGenTypeEnum, Long appId) {
        if (codeGenTypeEnum == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "代码生成类型为空");
        }
        return switch (codeGenTypeEnum) {
            case HTML -> {
                HtmlCodeResult htmlCode = aiCodeGeneratorService.generateHtmlCode(userMessage);
                yield CodeFileSaverExecutor.codeFileSaverExecutor(htmlCode, codeGenTypeEnum, appId);
            }
            case MULTI_FILE -> {
                MultiFileCodeResult multiFile = aiCodeGeneratorService.generateMutiFileCode(userMessage);
                yield CodeFileSaverExecutor.codeFileSaverExecutor(multiFile, codeGenTypeEnum, appId);
            }
            default -> {
                String errMsg = "不支持的生成类型" + codeGenTypeEnum.getValue();
                throw new BusinessException(ErrorCode.PARAMS_ERROR, errMsg);
            }
        };
    }

    /**
     * 生成代码文件,流式生成
     *
     * @param userMessage
     * @param codeGenTypeEnum
     * @return
     */
    public Flux<String> generateAndSaveStreamCode(String userMessage, CodeGenTypeEnum codeGenTypeEnum, Long appId) {
        if (codeGenTypeEnum == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "代码生成类型为空");
        }
        return switch (codeGenTypeEnum) {
            case HTML -> {
                Flux<String> result = aiCodeGeneratorService.generateHtmlStreamCode(userMessage);
                yield processCodeStream(result, codeGenTypeEnum, appId);
            }
            case MULTI_FILE -> {
                Flux<String> result = aiCodeGeneratorService.generateMutiFileStreamCode(userMessage);
                yield processCodeStream(result, codeGenTypeEnum, appId);
            }
            default -> {
                String errMsg = "不支持的生成类型" + codeGenTypeEnum.getValue();
                throw new BusinessException(ErrorCode.PARAMS_ERROR, errMsg);
            }
        };
    }

    /**
     * 通用流式代码处理方法
     *
     * @param fluxResult
     * @param codeGenTypeEnum
     * @return
     */
    private Flux<String> processCodeStream(Flux<String> fluxResult, CodeGenTypeEnum codeGenTypeEnum, Long appId) {
        StringBuffer codeBuilder = new StringBuffer();
        return fluxResult
                .doOnNext(codeBuilder::append)
                .doOnComplete(
                        // 保存文件
                        () -> {
                            try {
                                String code = codeBuilder.toString();
                                Object codeParsed = CodeParseExecutor.codeParseExecutor(code, codeGenTypeEnum);
                                File saveDir = CodeFileSaverExecutor.codeFileSaverExecutor(codeParsed, codeGenTypeEnum, appId);
                                log.info("保存文件成功,路径为：{}", saveDir.getAbsolutePath());
                            } catch (Exception e) {
                                log.error("保存文件失败：{}", e.getMessage());
                            }
                        }
                );
    }
}